package com.itheima.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.WmMaterialDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.itheima.Utils.WMThreadLocal;
import com.itheima.mapper.MaterialMapper;
import com.itheima.minio.utils.MinioUtils;
import com.itheima.service.MaterialService;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.UUID;

/**
 * @author yunfei
 * @date 2022年10月16日 17:20
 */
@Service
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, WmMaterial> implements MaterialService {

    @Autowired
    private MinioUtils minioUtils;

    /**
     * 自媒体端素材上传的业务实现
     *
     * @param multipartFile
     * @return
     */
    @Override
    public ResponseResult uploadPic(MultipartFile multipartFile) throws IOException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, ServerException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InsufficientDataException, InternalException {
        if (ObjectUtil.isNull(multipartFile)) return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        // 校验图片格式
        // 获取文件的原始名称
        String originalFilename = multipartFile.getOriginalFilename();
        // 截取文件的扩展名
        String extName = FileUtil.extName(originalFilename);
        // 判断是否是允许的后缀名 .jpg  png
        if (!StrUtil.containsAny(multipartFile.getContentType(), "image/png", "image/jpeg")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_IMAGE_FORMAT_ERROR);
        }
        // 校验图片大小
        if (multipartFile.getSize() / 1024 / 1024 > 2) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "图片大小不能超过2M");
        }
        // 给图片重命名
        String newFileName = UUID.randomUUID().toString() + "." + extName;

        // 给图片设置存储目录
        // 根据日期做目录分离  每天一个新的目录
        // 2022 / 10 /16
        // 直接在上传到minio的时候把路径给拼接上


        // 使用Minio的工具完成图片的上传
        minioUtils.putObject("", multipartFile, DateTime.now().toString("yyyy/MM/dd") + "/" + newFileName, multipartFile.getContentType());

        // 拼凑一个minio的返回路径
        String picUrl = minioUtils.getBasisUrl() + DateTime.now().toString("yyyy/MM/dd") + "/" + newFileName;

        // 把这个数据存储到数据库中
        WmMaterial wmMaterial = new WmMaterial();
        wmMaterial.setUserId(WMThreadLocal.get());
        wmMaterial.setUrl(picUrl);
        wmMaterial.setType(Convert.toShort(0));
        wmMaterial.setIsCollection(Convert.toShort(0));
        wmMaterial.setCreatedTime(new Date());
        save(wmMaterial);
        return ResponseResult.okResult(wmMaterial);
    }

    /**
     * 素材的分页查询
     *
     * @param materialDto
     * @return
     */
    @Override
    public ResponseResult materialList(WmMaterialDto materialDto) {
        // 校验分页参数即可
        materialDto.checkParam();
        // 直接分页查询即可
        Page<WmMaterial> materialPage = page(new Page<>(materialDto.getPage(), materialDto.getSize()),
                Wrappers.lambdaQuery(WmMaterial.class)
                        .eq(WmMaterial::getIsCollection, materialDto.getIsCollection())
                        .eq(WmMaterial::getUserId, WMThreadLocal.get())
        );
        PageResponseResult result = new PageResponseResult(Convert.toInt(materialPage.getCurrent()),
                materialDto.getSize(), Convert.toInt(materialPage.getTotal()));
        result.setData(materialPage.getRecords());
        return result;
    }


}
